﻿using Microsoft.IdentityModel.Tokens;

using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;

namespace anydata.Handlers
{
    public class TokenHanlder
    {
        readonly static byte[] AccessSecret = Encoding.UTF8.GetBytes("ogocns-organization");
        public static string Create(Dictionary<string, string> data, int days = 0)
        {
            var claims = new List<Claim>();
            foreach (var key in data.Keys)
            {
                claims.Add(new Claim(key, data[key]));
            }
            var secretKey = new SymmetricSecurityKey(AccessSecret);
            var algorithm = SecurityAlgorithms.HmacSha256;
            var signingCredentials = new SigningCredentials(secretKey, algorithm);
            var expire = days > 0 ? DateTime.Now.AddDays(days) : DateTime.Now.AddSeconds(Config.AccessExpire);
            var jwtSecurityToken = new JwtSecurityToken(
                null, null, claims, DateTime.Now, expire, signingCredentials);
            var token = new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken);
            return token;
        }

        public static TokenModel Read(string accessToken)
        {
            try
            {
                ulong userId = 0, belongId = 0;
                accessToken = accessToken.Replace("Bearer ", "");
                var token = new JwtSecurityTokenHandler().ValidateToken(accessToken, new TokenValidationParameters()
                {
                    ValidateIssuer = false,
                    ValidateAudience = false,
                    ValidateIssuerSigningKey = true,
                    ClockSkew = TimeSpan.FromSeconds(30),
                    IssuerSigningKey = new SymmetricSecurityKey(AccessSecret),
                }, out var _);
                foreach (var item in token.Claims)
                {
                    if (item.Type.ToLower() == "userid")
                    {
                        ulong.TryParse(item.Value, out userId);
                    }
                    if (item.Type.ToLower() == "belongid")
                    {
                        ulong.TryParse(item.Value, out belongId);
                    }
                }
                if (userId == 0)
                {
                    throw new Exception("authorization is error.");
                }
                if (belongId == 0)
                {
                    belongId = userId;
                }
                return new TokenModel()
                {
                    UserId = userId,
                    BelongId = belongId,
                };
            }
            catch (SecurityTokenExpiredException)
            {
                throw new Exception("accessToken is expired.");
            }
            catch
            {
                throw new Exception("accessToken validate is error.");
            }
        }
    }
}
